<?php
/**
 * Created by PhpStorm.
 * User: baidu
 * Date: 17/8/6
 * Time: 上午2:45
 */

namespace app\common\lib\exception;

use app\common\lib\Aes;
use think\exception\Handle;
use think\App;
use think\Log;
use think\Config;

class ApiHandleException extends Handle
{

    /**
     * http 状态码
     * @var int
     */
    public $httpCode = 200;
    public $code = 0;
    public $message = '服务异常，稍后重试。';

    public function render(\Exception $e)
    {

        if (function_exists('config') && config('app_debug') == true)
        {
            return parent::render($e);
        }
        if ($e instanceof ApiException)
        {
            $this->httpCode = $e->httpCode;
            $this->code = $e->code;
            $this->message = $e->message;
        }
        if (function_exists('show'))
        {
            return show($this->code, $this->message, [], $this->httpCode);
        } else
        {
            return parent::render($e);
        }
    }

    /**
     * 对异常进行日志记录
     * Report or log an exception.
     * @param \Exception $exception
     * @return void
     */
    public function report(\Exception $exception)
    {
        try
        {
            $header = function_exists('request') ? request()->header() : [];
            $access_token = (isset($header['access-token']) && $header['access-token']) ? (new Aes())->decryptWithOpenssl($header['access-token']) : '';
            $header_info = [
                'model' => $header['model'] ?? '',
                'channel' => $header['channel'] ?? '',
                'version' => $header['version'] ?? '',
                'access-token' => $access_token,
                'user-agent' => $header['user-agent'] ?? '',
                'timezone' => $header['timezone'] ?? 8
            ];
        }
        catch (\Exception $e)
        {
            echo $e->getMessage();
            $header_info = [
                'model' => '',
                'channel' => '',
                'version' => '',
                'access-token' => '',
                'user-agent' => '',
                'timezone' => 8
            ];
        }

        // 判断是否为忽略当前异常
        if (!$this->isIgnoreReport($exception))
        {
            // 收集异常数据
            if (App::$debug)
            {
                $data = [
                    'file' => $exception->getFile(),
                    'line' => $exception->getLine(),
                    'message' => $exception->getMessage(),
                    'header' => json_encode($header_info),
                    'code' => $exception->getCode(),
                ];
                $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}] 请求头 {$data['header']}";
            } else
            {
                $data = [
                    'file' => $exception->getFile(),
                    'line' => $exception->getLine(),
                    'code' => $exception->getCode(),
                    'header' => json_encode($header_info),
                    'message' => $this->getMessage($exception),
                ];
                $log = "[{$data['file']}:{$data['line']}] \r\n [{$data['code']}]{$data['message']} 请求头 {$data['header']}";
            }

            if (Config::get('record_trace'))
            {
                $log .= "\r\n" . $exception->getTraceAsString();
            }
            // 登录失效不往错误日志写入
//            if (!in_array($exception->getCode(), [403, 405, 406], false))
            if (!in_array($exception->getCode(), [403, 405, 406, 407], false))
            {
                Log::record($log, 'error');
            }

        }
    }
}
